import 'package:concierge/app/models/myvertu_user_bean.dart';
import 'package:concierge/app/models/phone_cc.dart';
import 'package:concierge/app/models/user_bean.dart';
import 'package:concierge/app/pages/bind_phone/logic.dart';
import 'package:concierge/app/req/provider/CenterApiProvider.dart';
import 'package:concierge/app/req/provider/LifeApiProvider.dart';
import 'package:concierge/app/routes/app_routes.dart';
import 'package:concierge/app/utils/ApiUtil.dart';
import 'package:concierge/app/utils/Cacheutil.dart';
import 'package:concierge/app/widgets/CommonDialog.dart';
import 'package:concierge/config/config.gen.dart';
import 'package:concierge/generated/locales.g.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
import 'package:google_sign_in/google_sign_in.dart';

class UserApi {
  final CenterApiProvider centerProvider;
  final LifeApiProvider lifeProvider;
  UserApi._(this.centerProvider, this.lifeProvider);
  static UserApi? _instance;
  static UserApi get instance {
    _instance ??= UserApi._(
      Get.find<CenterApiProvider>(),
      Get.find<LifeApiProvider>(),
    );
    return _instance!;
  }

  Future<UserBean?> loginBySms({
    required String phone,
    required String sms,
    required CCListElement cc,
  }) async {
    Map<String, String> headers = {};
    var map = await SmsLoginParam.create(cc.callingCode, phone, sms);
    headers["Authorization"] = await getAuth(vType: VType.SMS, param: map);
    headers['active'] = 'login';
    var res = await lifeProvider.post_(
      "user/login",
      {"code": sms, "mobile": phone, "cc": cc.callingCode, ...map.m},
      headers: headers,
      decoder: UserBean.fromJson,
    );
    await saveUser(res.body);
    return res.body;
  }

  Future<Response> loginByEmail({
    required String email,
    required String code,
  }) async {
    Map<String, String> headers = {};
    var map = await EmailLoginParam.create(email, code);
    headers["Authorization"] = await getAuth(vType: VType.EMAIL, param: map);
    headers['active'] = 'login';
    return await lifeProvider.post_("user/login", {
      "code_email": code,
      "email": email,
    }, headers: headers);
  }

  Future loginByBindEmail({
    required String phone,
    required String code_phone,
    required String session_id,
    required String email,
    required String code_email,
    required int cc,
  }) async {
    Map<String, String> headers = {};
    var map = await EmailLoginParam.create(email, code_email);
    headers["Authorization"] = await getAuth(vType: VType.EMAIL, param: map);
    headers['active'] = 'login';
    var res = await lifeProvider.post_(
      "user/login",
      {
        "cc": cc,
        "code_mobile": code_phone,
        "code_email": code_email,
        "email": email,
        "session_id": session_id,
        "mobile": phone,
      },
      headers: headers,
      decoder: UserBean.fromJson,
    );
    var user = res.body;
    await saveUser(user);
    return user;
  }

  Future<void> loginByGoogle() async {
    try {
      if (!GoogleSignIn.instance.supportsAuthenticate()) {
        SmartDialog.showToast(LocaleKeys.google_login_not_supported.tr);
        return;
      }
      await GoogleSignIn.instance.initialize(
        clientId: yamlMap.google_login.clientId,
        serverClientId: yamlMap.google_login.serverClientId,
        hostedDomain: yamlMap.google_login.hostedDomain,
      );
      var lightAccount = await GoogleSignIn.instance
          .attemptLightweightAuthentication();
      if (lightAccount != null) {
        if (lightAccount.authentication.idToken == null) {
          SmartDialog.showToast("登录失败");
          return;
        }
        await attempLogin(
          displayName: lightAccount.displayName ?? "",
          idToken: lightAccount.authentication.idToken ?? "",
        );
      } else {
        print("轻量登录失败，开始交互登录");
        var account = await GoogleSignIn.instance.authenticate(
          scopeHint: ["email", "profile"],
        );
        final GoogleSignInAuthentication auth = account.authentication;
        if (auth.idToken == null) {
          SmartDialog.showToast("登录失败");
          return;
        }
        await attempLogin(
          displayName: account.displayName ?? "",
          idToken: account.authentication.idToken ?? "",
        );
      }
    } catch (e) {
      SmartDialog.showToast("登录失败");
    }
  }

  Future loginByBindGoogle({
    required String phone,
    required String code_phone,
    required session_id,
    required int cc,
    required String idToken,
  }) async {
    Map<String, String> headers = {};
    var map = await GoogleLoginParam.create(idToken);
    headers["Authorization"] = await getAuth(vType: VType.GOOGLE, param: map);
    headers['active'] = 'login';
    var res = await lifeProvider.post_(
      "user/login",
      {
        "cc": cc,
        "code_mobile": code_phone,
        "session_id": session_id,
        "mobile": phone,
      },
      headers: headers,
      decoder: UserBean.fromJson,
    );
    if (res.statusCode == 422) {
      SmartDialog.showToast("当前手机号已被使用");
      return null;
    }
    var user = res.body;
    await saveUser(user);
    return user;
  }

  Future<void> attempLogin({
    required String displayName,
    required String idToken,
  }) async {
    Map<String, String> headers = {};
    var map = await GoogleLoginParam.create(idToken ?? "");
    headers["Authorization"] = await getAuth(vType: VType.GOOGLE, param: map);
    headers['active'] = 'login';
    var res = await lifeProvider.post_("user/login", {}, headers: headers);
    var body = res.body as Map;
    if (body.containsKey("session_id") && "${body['session_id']}".isNotEmpty) {
      body['idToken'] = idToken;
      await showCommonDialog(
        content: LocaleKeys.bind_phone_required.tr,
        dialogBtnParam: DialogButtonParam(
          onlyOneButton: false,
          showDivider: false,
          rightText: LocaleKeys.go_bind.tr,
          leftText: LocaleKeys.cancel.tr,
          onRightTap: () {
            Get.toNamed(
              Routes.bind_phone,
              arguments: BindPhoneParam(type: BindPhoneType.google, obj: body),
            );
          },
        ),
      );
    } else {
      await saveUser(UserBean.fromJson(body));
      SmartDialog.showToast("登录成功,欢迎:${displayName}!，登录结果：${res.statusText}");
      Get.offAllNamed(Routes.main);
    }
  }

  Future<UserBean?> loginWithMyVertu(
    MyvertuUserBean myvertuUserBeanFromJson,
  ) async {
    Map<String, String> headers = {};
    var map = await VertuLoginParam.create(myvertuUserBeanFromJson.id ?? "");
    headers["Authorization"] = await getAuth(vType: VType.VERTU, param: map);
    headers['active'] = 'login';
    headers['corp'] = 'vertu';
    var res = await lifeProvider.post_("user/login", {
      "cc": myvertuUserBeanFromJson.cc,
      "mobile": myvertuUserBeanFromJson.mobile,
    }, headers: headers);
    if (res.statusCode != 200) {
      return null;
    }

    var body = res.body as Map;

    var user = UserBean.fromJson(body);
    await saveUser(user);
    return user;
  }
}
